import { defineStore } from "pinia";
import { router } from "@/router";
import { sessionStg } from "@/utils";
import { RouteLocationNormalizedLoaded as RouteLNL } from "vue-router";
import {
  type TabRoute,
  type TabPosition,
  getIndexInTabs,
  getIndexByRouteName,
  route2Tab,
  getLeafRouter,
} from "./helpers";

export const useTabStore = defineStore("tab-store", () => {
  // state
  const tabs = ref<TabRoute[]>([]);
  const activeTabPath = ref("");
  const homeTab = ref<TabRoute>({
    name: "root",
    path: "/",
    meta: {
      title: "Root",
    },
    scrollPos: {
      left: 0,
      top: 0,
    },
  });

  // getter
  const activeTabIndex = computed(() =>
    getIndexInTabs(tabs, activeTabPath.value)
  );
  const activeTab = computed(() => tabs.value[activeTabIndex.value]);

  // action
  /** 添加tab */
  const addTab = (route: RouteLNL) => {
    const tab = route2Tab(route);

    // 判断该tab是否已存在
    if (getIndexInTabs(tabs, tab.path) > -1) return;

    const index = getIndexByRouteName(tabs.value, route.name as string);

    if (index === -1) {
      tabs.value.push(tab);
    }
  };

  /** 初始化首页页签路由 */
  const initHomeTab = (routes: AuthRoute.Route[]) => {
    const findHome = getLeafRouter(routes);
    homeTab.value = route2Tab(findHome);
  };

  /** 重置tab状态 */
  const resetTabStore = () => {
    useTabStore().$reset();
    sessionStg.set("multiTabRoutes", []);
  };

  /** 缓存tabs */
  const cacheTabRoutes = () => {
    sessionStg.set("multiTabRoutes", tabs.value);
  };

  /** 从缓存中获取tabs */
  const getCacheTabRoutes = (): TabRoute[] => {
    const data: TabRoute[] = sessionStg.get("multiTabRoutes") || [];
    return data.map((item) => ({
      ...item,
      scrollPos: {
        left: 0,
        top: 0,
      },
    }));
  };

  /** 切换tab */
  const setActiveTab = (fullPath: string) => {
    activeTabPath.value = fullPath;
  };

  /** 删除tab */
  const removeTab = async (fullPath: string) => {
    const isActive = activeTabPath.value === fullPath;
    const updateTabs = tabs.value.filter((tab) => tab.path !== fullPath);
    if (!isActive) tabs.value = updateTabs;
    if (isActive && updateTabs.length) {
      const tabIndex = getIndexInTabs(tabs, fullPath);
      const activePath = updateTabs[tabIndex - 1].path;
      const navigationFailure = await router.push(activePath);
      if (!navigationFailure) {
        tabs.value = updateTabs;
        setActiveTab(activePath);
      }
    }
  };

  /**
   * 清空tabs，只保留首页
   * @param excludes - 保留的多页签path
   */
  const clearTab = async (excludes: string[] = []) => {
    const homePath = homeTab.value?.path;
    const remain = [homePath, ...excludes];
    const hasActive = remain.includes(activeTabPath.value);
    const updateTabs = tabs.value.filter((tab) => remain.includes(tab.path));
    if (hasActive) tabs.value = updateTabs;
    if (!hasActive && updateTabs.length) {
      const activePath = updateTabs[updateTabs.length - 1].path;
      const navigationFailure = await router.push(activePath);
      if (!navigationFailure) {
        tabs.value = updateTabs;
        setActiveTab(activePath);
      }
    }
  };

  /** 清除左边tabs */
  const clearLeftTab = (fullPath: string) => {
    const index = getIndexInTabs(tabs, fullPath);
    if (index > -1) {
      const excludes = tabs.value.slice(index).map((item) => item.path);
      clearTab(excludes);
    }
  };

  /** 清除右边tabs */
  const clearRightTab = (fullPath: string) => {
    const index = getIndexInTabs(tabs, fullPath);
    if (index > -1) {
      const excludes = tabs.value.slice(0, index + 1).map((item) => item.path);
      clearTab(excludes);
    }
  };

  /** 点击tab */
  const handleClickTab = async (fullPath: string) => {
    const isActive = activeTabPath.value === fullPath;
    if (!isActive) {
      const navigationFailure = await router.push(fullPath);
      if (!navigationFailure) setActiveTab(fullPath);
    }
  };

  /** 记录tab滚动位置 */
  const recordTabScrollPos = (fullPath: string, position: TabPosition) => {
    const index = getIndexInTabs(tabs, fullPath);
    if (index > -1) {
      tabs.value[index].scrollPos = position;
    }
  };

  /** 获取tab滚动位置 */
  const getTabScrollPos = (fullPath: string) => {
    const position = { left: 0, top: 0 };
    const index = getIndexInTabs(tabs, fullPath);
    if (index > -1) {
      Object.assign(position, tabs.value[index].scrollPos);
    }
    return position;
  };

  /** 初始化Tab状态 */
  const iniTabStore = (currentRoute: RouteLNL) => {
    const originTabs: TabRoute[] = getCacheTabRoutes();

    const hasHome = getIndexByRouteName(originTabs, homeTab.value!.name) > -1;
    if (!hasHome && homeTab.value!.name !== "root") {
      originTabs.unshift(homeTab.value!);
    }

    const isHome = currentRoute.fullPath === homeTab.value!.path;
    const index = getIndexByRouteName(originTabs, currentRoute.name as string);
    if (!isHome) {
      const currentTab = route2Tab(currentRoute);
      if (!currentRoute.meta.multiTab) {
        if (index > -1) {
          originTabs.splice(index, 1, currentTab);
        } else {
          originTabs.push(currentTab);
        }
      } else {
        const hasCurrent = getIndexInTabs(tabs, currentRoute.fullPath) > -1;
        if (!hasCurrent) {
          originTabs.push(currentTab);
        }
      }
    }

    tabs.value = originTabs;
    setActiveTab(currentRoute.fullPath);
  };

  return {
    tabs,
    homeTab,
    activeTab,
    activeTabPath,
    activeTabIndex,
    addTab,
    setActiveTab,
    initHomeTab,
    iniTabStore,
    resetTabStore,
    cacheTabRoutes,
    removeTab,
    clearTab,
    clearLeftTab,
    clearRightTab,
    handleClickTab,
    getTabScrollPos,
    recordTabScrollPos,
  };
});

export type { TabRoute };
